package logging

import (
	"time"

	"github.com/sirupsen/logrus"
)

type loggerImpl struct {
	logger     *logrus.Logger
	rootEntry  *logrus.Entry
	rootFields map[string]interface{}
}

func newloggerImpl(logger *logrus.Logger, fields map[string]interface{}) *loggerImpl {
	logImp := &loggerImpl{
		logger:     logger,
		rootEntry:  logger.WithFields(fields),
		rootFields: fields,
	}
	return logImp
}

//Printf ...
func (l *loggerImpl) Printf(format string, v ...interface{}) {
	l.rootEntry.Printf(format, v...)
}

//Fatal fatal
func (l *loggerImpl) Fatal(args ...interface{}) {
	l.rootEntry.Fatal(args...)
}

//Fatalf fatalf
func (l *loggerImpl) Fatalf(format string, args ...interface{}) {
	l.rootEntry.Fatalf(format, args...)
}

//Error error
func (l *loggerImpl) Error(args ...interface{}) {
	l.rootEntry.Error(args...)
}

//Errorf errorf
func (l *loggerImpl) Errorf(format string, args ...interface{}) {
	l.rootEntry.Errorf(format, args...)
}

//Warn warn
func (l *loggerImpl) Warn(args ...interface{}) {
	l.rootEntry.Warn(args...)
}

//Warnf warnf
func (l *loggerImpl) Warnf(format string, args ...interface{}) {
	l.rootEntry.Warnf(format, args...)
}

//Info info
func (l *loggerImpl) Info(args ...interface{}) {
	l.rootEntry.Info(args...)
}

//Infof infof
func (l *loggerImpl) Infof(format string, args ...interface{}) {
	l.rootEntry.Infof(format, args...)
}

//Debug debug
func (l *loggerImpl) Debug(args ...interface{}) {
	l.rootEntry.Debug(args...)
}

//Debugf debugf
func (l *loggerImpl) Debugf(format string, args ...interface{}) {
	l.rootEntry.Debugf(format, args...)
}

//Trace trace
func (l *loggerImpl) Trace(args ...interface{}) {
	l.rootEntry.Trace(args...)
}

//Tracef tracef
func (l *loggerImpl) Tracef(format string, args ...interface{}) {
	l.rootEntry.Tracef(format, args...)
}

//WithField withfield
func (l *loggerImpl) WithField(fieldName string, fieldValue interface{}) Log {
	mp := make(map[string]interface{})
	for k, v := range l.rootFields {
		mp[k] = v
	}
	mp[fieldName] = fieldValue
	return newloggerImpl(l.logger, mp)
}

//WithCostField ...
func (l *loggerImpl) WithCostField(start time.Time) Log {
	return l.WithField(LogFieldCost, time.Since(start)/time.Millisecond)
}

//WithFields ...
func (l *loggerImpl) WithFields(fields map[string]interface{}) Log {
	mp := make(map[string]interface{})
	for k, v := range l.rootFields {
		mp[k] = v
	}
	for k, v := range fields {
		mp[k] = v
	}
	return newloggerImpl(l.logger, mp)
}

//IsDebugEnabled is debug level enabled
func (l *loggerImpl) IsDebugEnabled() bool {
	return l.logger.GetLevel() >= logrus.DebugLevel
}

//IsTraceEnabled is trace level enabled
func (l *loggerImpl) IsTraceEnabled() bool {
	return l.logger.GetLevel() == logrus.TraceLevel
}

// ElapsedTime 打印函数用时（毫秒）
// 用法: defer ElapsedTime("methodName", time.Now())
func (l *loggerImpl) ElapsedTime(methodName string, start time.Time) {
	l.rootEntry.Trace("stats")
}

//GetLevel get log level
func (l *loggerImpl) GetLevel() LogLevel {
	return LogLevel(l.logger.GetLevel())
}
